function [w,b,a] = linearSvm(x,y,C)

% inputs x
% labels y {-1,+1}

% ARGS
[d,n] = size(x);
y = y(:)';

% HARD MARGIN
if (nargin==2)
  cvx_begin quiet
    cvx_solver sedumi
    variable w(d)
    variable b
    minimize (w'*w)
    subject to
      (w'*x + b).*y >= 1
  cvx_end
end

% SOFT MARGIN
if (nargin==3)
  cvx_begin quiet
    cvx_solver sedumi
    variable w(d)
    variable b
    variable s(n) nonnegative
    minimize (w'*w + C*sum(s))
    subject to
      (w'*x + b).*y >= 1 - s'
  cvx_end
end

% DUAL
a = sparse(zeros(1,n));
if (~isnan(b))
  a = linearSvmPrimalToDual(w,b,x,y);
end
return;

%%%%%%%%%%%%%%%%%%%%%%

function a = linearSvmPrimalToDual(w,b,x,y)

[d,n] = size(x);
tol = 1e-4;

z = (w'*x + b).*y;
i = find(z<1+tol);

cvx_begin quiet
 variable aa(length(i)) nonnegative
 minimize sum(aa)
 subject to
   x(:,i)*(aa.*y(i)') == w
   y(i)*aa == 0
cvx_end

a = zeros(1,n);
a(i) = aa;
a = sparse(a);
return;

%%%%%%%%%%%%%%%%%%%%%%
